using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using Toolbox.Model;

namespace Toolbox.Forms
{
    /// <summary>
    /// 自定义TabControl，用于控制页签切换行为和处理页签拖拽
    /// 作者：huobing
    /// </summary>
    public class CustomTabControl : TabControl
    {
        // 拖拽相关字段
        private bool _isDragging = false;
        private TabPage? _draggedTab = null;
        private int _dragStartIndex = -1;
        private Point _dragStartPoint = Point.Empty;
        private const int DragThreshold = 10; // 拖拽阈值，像素
        
        // 点击相关字段
        private TabPage? _clickedTab = null;
        private bool _isClicking = false;
        private bool _isMouseDown = false; // 新增：标记鼠标是否按下
        
        // 页签映射字典
        private readonly Dictionary<TabPage, BaseTabPage> _tabPageMappings = new Dictionary<TabPage, BaseTabPage>();
        
        public CustomTabControl()
        {
            // 启用拖放
            this.AllowDrop = true;
        }
        
        /// <summary>
        /// 重写OnMouseDown方法，处理鼠标按下事件
        /// </summary>
        /// <param name="e">鼠标事件参数</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                // 获取鼠标下的页签
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    Rectangle tabRect = this.GetTabRect(i);
                    if (tabRect.Contains(e.Location))
                    {
                        // 记录点击的页签和起始点
                        _clickedTab = this.TabPages[i];
                        _isMouseDown = true; // 标记鼠标按下
                        _isClicking = true;
                        _dragStartPoint = e.Location;
                        _draggedTab = this.TabPages[i];
                        _dragStartIndex = i;
                        
                        // 标记开始拖拽准备状态
                        _isDragging = false;
                        
                        // 不设置_isDragging为true，等待鼠标移动超过阈值
                        break;
                    }
                }
            }
            
            base.OnMouseDown(e); // 调用基类方法确保正常功能
        }
        
        /// <summary>
        /// 重写OnMouseMove方法，处理鼠标移动事件
        /// </summary>
        /// <param name="e">鼠标事件参数</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            // 只有在鼠标按下时才处理拖拽逻辑
            if (_isMouseDown && !_isDragging && _draggedTab != null && _dragStartPoint != Point.Empty)
            {
                // 计算鼠标移动的距离
                int deltaX = Math.Abs(e.X - _dragStartPoint.X);
                int deltaY = Math.Abs(e.Y - _dragStartPoint.Y);
                
                // 如果移动距离超过阈值，开始拖拽操作
                if (deltaX > DragThreshold || deltaY > DragThreshold)
                {
                    _isDragging = true;
                    // 开始拖拽时重置点击状态
                    _isClicking = false;
                    _clickedTab = null;
                    
                    // 开始拖拽操作
                    this.DoDragDrop(_draggedTab, DragDropEffects.Move);
                }
            }
            // 如果已经在拖拽状态，则继续拖拽
            else if (_isDragging && _draggedTab != null)
            {
                // 继续拖拽操作
                this.DoDragDrop(_draggedTab, DragDropEffects.Move);
            }
            
            base.OnMouseMove(e);
        }
        
        /// <summary>
        /// 重写OnMouseUp方法，处理鼠标抬起事件
        /// </summary>
        /// <param name="e">鼠标事件参数</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            // 重置鼠标按下状态
            _isMouseDown = false;
            
            // 如果是点击操作（没有进入拖拽状态），则保持正常点击行为
            if (_isClicking && !_isDragging && _clickedTab != null)
            {
                // 这是一个点击操作，不需要特殊处理，让TabControl自己处理选中逻辑
            }
            
            // 重置所有拖拽相关状态
            _isDragging = false;
            _draggedTab = null;
            _dragStartIndex = -1;
            _dragStartPoint = Point.Empty;
            
            // 重置点击状态
            _isClicking = false;
            _clickedTab = null;
            
            base.OnMouseUp(e); // 调用基类方法确保正常功能
        }
        
        /// <summary>
        /// 重写OnDragOver方法，处理拖拽悬停事件
        /// </summary>
        /// <param name="e">拖拽事件参数</param>
        protected override void OnDragOver(DragEventArgs e)
        {
            if (e.Data?.GetData(typeof(TabPage)) is TabPage draggedTab)
            {
                e.Effect = DragDropEffects.Move;
                
                // 获取鼠标位置对应的页签索引
                Point clientPoint = this.PointToClient(new Point(e.X, e.Y));
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    Rectangle tabRect = this.GetTabRect(i);
                    if (tabRect.Contains(clientPoint) && this.TabPages[i] != draggedTab)
                    {
                        // 如果鼠标悬停在另一个页签上，显示移动效果
                        return;
                    }
                }
            }
            
            base.OnDragOver(e);
        }
        
        /// <summary>
        /// 重写OnDragDrop方法，处理拖拽放下事件
        /// </summary>
        /// <param name="e">拖拽事件参数</param>
        protected override void OnDragDrop(DragEventArgs e)
        {
            if (e.Data?.GetData(typeof(TabPage)) is TabPage draggedTab && _draggedTab != null)
            {
                // 获取目标位置
                Point clientPoint = this.PointToClient(new Point(e.X, e.Y));
                int targetIndex = -1;
                
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    Rectangle tabRect = this.GetTabRect(i);
                    if (tabRect.Contains(clientPoint))
                    {
                        targetIndex = i;
                        break;
                    }
                }
                
                // 如果找到了有效目标位置，且不是当前位置
                if (targetIndex >= 0 && targetIndex != _dragStartIndex)
                {
                    // 移动页签
                    this.TabPages.Remove(draggedTab);
                    this.TabPages.Insert(targetIndex, draggedTab);
                    
                    // 更新TabRegistry中的页签顺序
                    UpdateTabOrderInRegistry();
                }
            }
            
            // 拖拽完成后重置状态
            _isDragging = false;
            _draggedTab = null;
            _dragStartIndex = -1;
            _dragStartPoint = Point.Empty;
            _isMouseDown = false; // 重置鼠标按下状态
            
            base.OnDragDrop(e);
        }
        
        /// <summary>
        /// 创建所有页签
        /// </summary>
        public void CreateAllTabs()
        {
            // 获取所有已启用的页签实例，已经按TabOrder排序
            var enabledTabs = TabRegistry.GetEnabledTabs();
            
            // 按顺序创建页签，确保页签按正确顺序显示
            foreach (var page in enabledTabs)
            {
                TabPage tab = new TabPage(page.TabName)
                {
                    Name = $"tab{page.TabOrder}" // 设置页签名称为tab+序号
                };
                
                page.InitializePage(tab, (MainForm)this.FindForm()!);
                
                this.TabPages.Add(tab);
                _tabPageMappings[tab] = page;
            }
        }
        
        /// <summary>
        /// 添加单个页签
        /// </summary>
        /// <param name="tabName">要添加的页签名称</param>
        /// <returns>是否成功添加页签</returns>
        public bool AddTab(string tabName)
        {
            try
            {
                // 获取页签类型
                Type? tabType = TabRegistry.GetTabType(tabName);
                if (tabType == null)
                {
                    return false;
                }
                
                // 创建页签实例
                var page = (BaseTabPage)Activator.CreateInstance(tabType)!;
                
                // 创建TabPage
                TabPage tab = new TabPage(page.TabName)
                {
                    Name = $"tab{page.TabOrder}" // 设置页签名称为tab+序号
                };
                
                // 初始化页签
                page.InitializePage(tab, (MainForm)this.FindForm()!);
                
                // 查找正确的插入位置，按TabOrder排序
                int insertIndex = 0;
                for (int i = 0; i < this.TabPages.Count; i++)
                {
                    var existingTab = this.TabPages[i];
                    if (existingTab.Name.StartsWith("tab"))
                    {
                        int existingOrder;
                        if (int.TryParse(existingTab.Name.Substring(3), out existingOrder) && existingOrder < page.TabOrder)
                        {
                            insertIndex = i + 1;
                        }
                        else
                        {
                            break; // 找到正确的插入位置
                        }
                    }
                }
                
                // 在正确的位置插入页签
                this.TabPages.Insert(insertIndex, tab);
                _tabPageMappings[tab] = page;
                
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"添加页签失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// 移除单个页签
        /// </summary>
        /// <param name="tabName">要移除的页签名称</param>
        /// <returns>是否成功移除页签</returns>
        public bool RemoveTab(string tabName)
        {
            try
            {
                // 查找要移除的页签
                TabPage? tabToRemove = null;
                foreach (TabPage tab in this.TabPages)
                {
                    if (tab.Text == tabName)
                    {
                        tabToRemove = tab;
                        break;
                    }
                }
                
                if (tabToRemove == null)
                {
                    return false;
                }
                
                // 如果移除的是当前选中的页签，需要切换到其他页签
                bool wasSelected = (tabToRemove == this.SelectedTab);
                int selectedIndex = this.SelectedIndex;
                
                // 从映射字典中移除
                _tabPageMappings.Remove(tabToRemove);
                
                // 从TabControl中移除
                this.TabPages.Remove(tabToRemove);
                
                // 如果移除的是当前选中的页签，尝试选中其他页签
                if (wasSelected && this.TabPages.Count > 0)
                {
                    // 尝试选中原来的索引位置，如果超出范围则选中最后一个
                    if (selectedIndex < this.TabPages.Count)
                    {
                        this.SelectedIndex = selectedIndex;
                    }
                    else
                    {
                        this.SelectedIndex = this.TabPages.Count - 1;
                    }
                }
                
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"移除页签失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// 更新TabRegistry中的页签顺序
        /// </summary>
        public void UpdateTabOrderInRegistry()
        {
            // 获取所有页签状态
            var allTabStatuses = TabRegistry.GetAllTabStatuses();
            
            // 更新页签顺序
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                TabPage tabPage = this.TabPages[i];
                var tabStatus = allTabStatuses.FirstOrDefault(s => s.Name == tabPage.Text);
                if (tabStatus != null)
                {
                    tabStatus.Order = i + 1; // 页签顺序从1开始
                    TabRegistry.UpdateTabStatus(tabStatus);
                }
            }
        }
        
        /// <summary>
        /// 通知所有页签窗口高度变化
        /// </summary>
        /// <param name="currentHeight">当前窗口高度</param>
        public void NotifyTabsOfHeightChange(int currentHeight)
        {
            // 多重安全检查
            if (this == null)
                return;

            // 获取主窗口引用
            MainForm? mainForm = this.FindForm() as MainForm;
            if (mainForm == null)
                return;

            // 遍历所有TabPage控件
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                TabPage tabPage = this.TabPages[i];
                if (tabPage == null)
                    continue;
                     
                if (_tabPageMappings.TryGetValue(tabPage, out BaseTabPage? tabPageImpl))
                {
                    if (tabPageImpl != null)
                    {
                        // 调用对应BaseTabPage实现类的OnWindowHeightChanged方法
                        // 传递当前窗口高度而不是高度变化值
                        tabPageImpl.OnWindowHeightChanged(tabPage!, mainForm, currentHeight);
                    }
                }
            }
        }
        
        /// <summary>
        /// 获取页签对应的BaseTabPage实例
        /// </summary>
        /// <param name="tabPage">页签控件</param>
        /// <returns>对应的BaseTabPage实例</returns>
        public BaseTabPage? GetTabPageMapping(TabPage tabPage)
        {
            _tabPageMappings.TryGetValue(tabPage, out BaseTabPage? tabPageImpl);
            return tabPageImpl;
        }
    }
    
    /// <summary>
    /// 页签拖拽事件参数
    /// 作者：huobing
    /// </summary>
    public class TabDragEventArgs : EventArgs
    {
        /// <summary>
        /// 被拖拽的页签
        /// </summary>
        public TabPage DraggedTab { get; }
        
        /// <summary>
        /// 拖拽起始位置
        /// </summary>
        public int OriginalIndex { get; }
        
        /// <summary>
        /// 拖拽目标位置
        /// </summary>
        public int NewIndex { get; }
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="draggedTab">被拖拽的页签</param>
        /// <param name="originalIndex">拖拽起始位置</param>
        /// <param name="newIndex">拖拽目标位置</param>
        public TabDragEventArgs(TabPage draggedTab, int originalIndex, int newIndex)
        {
            DraggedTab = draggedTab;
            OriginalIndex = originalIndex;
            NewIndex = newIndex;
        }
    }
    
    /// <summary>
    /// 页签点击事件参数
    /// 作者：huobing
    /// </summary>
    public class TabClickEventArgs : EventArgs
    {
        /// <summary>
        /// 被点击的页签
        /// </summary>
        public TabPage ClickedTab { get; }
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="clickedTab">被点击的页签</param>
        public TabClickEventArgs(TabPage clickedTab)
        {
            ClickedTab = clickedTab;
        }
    }
}